package game;

import game.engine.ABGameEngineImpl;
import game.engine.GameEngineImpl;
import game.engine.IGameEngine;
import game.evaluator.IMorrisGameEvaluator;
import game.evaluator.MorrisGameEvaluatorImpl;
import game.evaluator.MorrisGameEvaluatorImprovedImpl;
import game.util.StringUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

public class MorrisGame {

	public static void main(String[] args) {
		if (args.length < 3 || args.length > 4) {
			System.out
					.println("Usage: java MorrisGame inFile outFile depth [1-8]");
			System.out.println("Option 1: \"MinMaxOpening\"");
			System.out.println("Option 2: \"MinMaxGame\"");
			System.out.println("Option 3: \"AlphaBeltaOpening\"");
			System.out.println("Option 4: \"AlphaBeltaGame\"");
			System.out.println("Option 5: \"BlackMinMaxOpening\"");
			System.out.println("Option 6: \"BlackMinMaxGame\"");
			System.out.println("Option 7: \"MinMaxOpeningImproved\"");
			System.out.println("Option 8: \"MinMaxGameImproved\"");
			System.exit(-1);
		}
		String input = args[0];
		String output = args[1];
		int dep = Integer.parseInt(args[2]);
		int opt = 1;
		if (args.length == 4) {
			try {
				opt = Integer.parseInt(args[3]);
			} catch (NumberFormatException e) {
				opt = 1;
			}
		}
		String board = null;
		try {
			Scanner cin = new Scanner(new File(input));
			board = cin.next();
			cin.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.exit(-2);
		}

		IMorrisGameEvaluator evaluator = null;
		IGameEngine engine = null;
		if ((opt - 1) / 2 == 3) {
			evaluator = new MorrisGameEvaluatorImprovedImpl();
		} else {
			evaluator = new MorrisGameEvaluatorImpl();
		}
		if ((opt - 1) / 2 == 1) {
			engine = new ABGameEngineImpl(evaluator);
		} else {
			engine = new GameEngineImpl(evaluator);
		}

		String bestBoard = null;
		if ((opt - 1) / 2 == 2) {
			if (opt % 2 == 0) {
				engine.runGame(StringUtils.swapAll(board, 'W', 'B'), dep);
				bestBoard = StringUtils
						.swapAll(engine.getBestBoard(), 'W', 'B');
				System.out.println(bestBoard + " " + engine.getLeafCnt() + " "
						+ engine.getEstimatScore());
			} else {
				engine.runOpening(StringUtils.swapAll(board, 'W', 'B'), dep);
				bestBoard = StringUtils
						.swapAll(engine.getBestBoard(), 'W', 'B');
				System.out.println(bestBoard + " " + engine.getLeafCnt() + " "
						+ engine.getEstimatScore());
			}
		} else {
			if (opt % 2 == 0) {
				engine.runGame(board, dep);
				bestBoard = engine.getBestBoard();
				System.out.println(bestBoard + " " + engine.getLeafCnt() + " "
						+ engine.getEstimatScore());
			} else {
				engine.runOpening(board, dep);
				bestBoard = engine.getBestBoard();
				System.out.println(bestBoard + " " + engine.getLeafCnt() + " "
						+ engine.getEstimatScore());
			}
		}

		try {
			PrintWriter pw = new PrintWriter(new File(output));
			pw.println(bestBoard);
			pw.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.exit(-3);
		}
	}
}
